package at.favre.lib.securesharedpreferences.slice;

import at.favre.lib.armadillo.Armadillo;
import at.favre.lib.armadillo.ArmadilloSharedPreferences;
import at.favre.lib.armadillo.SecureSharedPreferenceCryptoException;
import at.favre.lib.securesharedpreferences.ResourceTable;
import at.favre.lib.securesharedpreferences.util.TextUtils;
import at.favre.lib.securesharedpreferences.util.ToastDialogUtil;
import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Button;
import ohos.agp.components.Component;
import ohos.agp.components.TextField;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;
import timber.log.Timber;

public class MainAbilitySlice extends AbilitySlice implements Component.ClickedListener {

    private static final String TAG = "MainAbilitySlice";
    private static final int REQUEST_CODE = 10;
    static final String PREF_NAME = "myPrefs";
    static final String SECRET = "a secret";


    private TextField tfPassword;
    private TextField tfKey;
    private TextField tfValue;
    private Button btnInit;
    private Button btnGet;
    private Button btnSet;
    private Button btnClose;
    private Button btnChange;

    private ArmadilloSharedPreferences encryptedPreferences;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);
        tfPassword = (TextField) findComponentById(ResourceTable.Id_tf_password);
        tfKey = (TextField) findComponentById(ResourceTable.Id_tf_key);
        tfValue = (TextField) findComponentById(ResourceTable.Id_tf_value);
        btnInit = (Button) findComponentById(ResourceTable.Id_btn_init);
        btnGet = (Button) findComponentById(ResourceTable.Id_btn_get);
        btnSet = (Button) findComponentById(ResourceTable.Id_btn_set);
        btnClose = (Button) findComponentById(ResourceTable.Id_btn_close);
        btnChange = (Button) findComponentById(ResourceTable.Id_btn_change);

        btnInit.setClickedListener(this);
        btnGet.setClickedListener(this);
        btnSet.setClickedListener(this);
        btnClose.setClickedListener(this);
        btnChange.setClickedListener(this);

        onArmadilloClosed();
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_btn_init:
                btnInit();
                break;
            case ResourceTable.Id_btn_get:
                getValueByKey();
                break;
            case ResourceTable.Id_btn_set:
                setValueByKey();
                break;
            case ResourceTable.Id_btn_close:
                closeArmadillo();
                break;
            case ResourceTable.Id_btn_change:
                changePassword();
                break;
        }
    }

    private void btnInit() {
        Armadillo.Builder builder = Armadillo.create(this, PREF_NAME)
                .encryptionFingerprint(this, SECRET)
                .supportVerifyPassword(true);
        if (!TextUtils.isEmpty(tfPassword.getText())) {
            char[] password = new char[tfPassword.getText().length()];
            tfPassword.getText().getChars(0, tfPassword.getText().length(), password, 0);
            builder.password(password);
            encryptedPreferences = builder.build();
            if (encryptedPreferences.isValidPassword()) {
                onArmadilloInitialised();
            } else {
                onWrongPassword();
            }
        }
    }

    private void getValueByKey() {
        if (encryptedPreferences == null) {
            Timber.i("You have to init Armadillo first!");
            ToastDialogUtil.showToast(this, "You have to init Armadillo first!");
            return;
        } else if (TextUtils.isEmpty(tfKey.getText())) {
            Timber.i("Enter key to retrieve value");
            ToastDialogUtil.showToast(this, "Enter key to retrieve value");
            return;
        }

        try {
            String value = encryptedPreferences.getString(tfKey.getText(), null);
            if (value == null) {
                ToastDialogUtil.showToast(this, "No value found for this key");
                return;
            }
            tfValue.setText(value);
        } catch (SecureSharedPreferenceCryptoException ex) {
            ToastDialogUtil.showToast(this, "Error while decrypting data!");
        }
    }

    private void setValueByKey() {
        if (encryptedPreferences == null) {
            Timber.i("You have to init Armadillo first!");
            ToastDialogUtil.showToast(this, "You have to init Armadillo first!");
            return;
        } else if (TextUtils.isEmpty(tfKey.getText())) {
            Timber.i("Enter key to set a value");
            ToastDialogUtil.showToast(this, "Enter key to set a value");
            return;
        } else if (TextUtils.isEmpty(tfValue.getText())) {
            Timber.i("Value is empty");
            ToastDialogUtil.showToast(this, "Value is empty");
            return;
        }
        try {
            encryptedPreferences.putString(tfKey.getText(), tfValue.getText()).flush();
            ToastDialogUtil.showToast(this, "Saved!");
        } catch (SecureSharedPreferenceCryptoException ex) {
            ToastDialogUtil.showToast(this, "Error while encrypting data!");
        }
    }

    private void closeArmadillo() {
        if (encryptedPreferences == null) {
            Timber.i("You have to init Armadillo first!");
            ToastDialogUtil.showToast(this, "You have to init Armadillo first!");
            return;
        }
        encryptedPreferences.close();
        onArmadilloClosed();
    }

    private void changePassword() {
        presentForResult(new ChangePasswordSlice(), new Intent(), REQUEST_CODE);
    }

    private void onArmadilloInitialised() {
        Timber.i("armadillo init success");
        btnInit.setVisibility(Component.HIDE);
        tfKey.setEnabled(true);
        tfKey.requestFocus();
        tfKey.setText("");
        tfValue.setEnabled(true);
        tfValue.setText("");
        btnGet.setVisibility(Component.VISIBLE);
        btnSet.setVisibility(Component.VISIBLE);
        btnClose.setVisibility(Component.VISIBLE);
        btnChange.setVisibility(Component.VISIBLE);
    }

    private void onWrongPassword() {
        Timber.i("Incorrect password!");
        ToastDialogUtil.showToast(this, "Incorrect password!");
        onArmadilloClosed();
    }

    private void onArmadilloClosed() {
        btnInit.setVisibility(Component.VISIBLE);
        tfKey.setEnabled(false);
        tfKey.setText("");
        tfValue.setEnabled(false);
        tfValue.setText("");

        btnGet.setVisibility(Component.HIDE);
        btnSet.setVisibility(Component.HIDE);
        btnClose.setVisibility(Component.HIDE);
        btnChange.setVisibility(Component.HIDE);

        tfPassword.requestFocus();
    }

    @Override
    protected void onResult(int requestCode, Intent resultData) {
        super.onResult(requestCode, resultData);
        HiLog.info(new HiLogLabel(0, 0, TAG), "onResult");
        if (REQUEST_CODE == requestCode) {
            HiLog.info(new HiLogLabel(0, 0, TAG), "onAbilityResult REQUEST_CODE == requestCode");
            if (resultData != null) {
                HiLog.info(new HiLogLabel(0, 0, TAG), "onAbilityResult REQUEST_CODE == requestCode resultData != null");
                boolean isChangeSuccess = resultData.getBooleanParam(ChangePasswordSlice.KEY_RESULT, false);
                HiLog.info(new HiLogLabel(0, 0, TAG), "onAbilityResult REQUEST_CODE == requestCode resultData != null isChangeSuccess:" + isChangeSuccess);
                if (isChangeSuccess) {
                    onArmadilloClosed();
                    tfPassword.setText("");
                }
            }
        }
    }
}
